package sqldriver

import (
	"bufio"
	"database/sql"
	"flag"
	"fmt"
	//""gitee.com/hakwolf/dbmagic/golib/internal/modules/configdbg"
	"github.com/microsoft/go-mssqldb/msdsn"

	//_ "github.com/denisenkom/go-mssqldb"
	//"github.com/denisenkom/go-mssqldb/msdsn"
	_ "github.com/microsoft/go-mssqldb"
	"io"
	"log"
	"net/url"
	"os"
	"runtime"
	"testing"
)

var debug = flag.Bool("debug", true, "enable debugging")

//var password = flag.String("password", "admin", "the database password")
//var port *int = flag.Int("port", 8888, "the database port")
//var server = flag.String("server", "127.0.0.1", "the database server")
//var user = flag.String("user", "sa", "the database user")
//var database2 = flag.String("database", "master", "the database name")

func GetDB(server, user, password, database2 *string, port *int) (*sql.DB, error) {
	if *debug {
		fmt.Printf(" password:%s\n", *password)
		fmt.Printf(" port:%d\n", *port)
		fmt.Printf(" server:%s\n", *server)
		fmt.Printf(" user:%s\n", *user)
	}
	connString := fmt.Sprintf("server=%s;database=%s;user id=%s;password=%s;port=%d;encrypt=disable", *server, *database2, *user, *password, *port)
	if *debug {
		fmt.Printf(" connString:%s\n", connString)
	}
	db, err := sql.Open("mssql", connString)
	if err != nil {
		log.Fatal("Open connection failed:", err.Error())
		return nil, err
	}
	err = db.Ping()
	if err != nil {
		fmt.Print("PING:%s", err)
		return nil, err
	}
	return db, nil
}

func EXECmssqldbsqlNew(server, user, password *string, port *int, sql, dbname string) {
	db, err := getNewDB(server, user, password, &dbname, port)
	if err != nil {
		fmt.Println("Open connection failed:", err.Error())
		return
	}
	defer db.Close()
	_, err = db.Exec(sql)
	if err != nil {
		log.Println(err)
		return
	}

}

func getNewDB(server, user, password, database2 *string, port *int) (*sql.DB, error) {
	if *debug {
		fmt.Printf(" password:%s\n", *password)
		fmt.Printf(" port:%d\n", *port)
		fmt.Printf(" server:%s\n", *server)
		fmt.Printf(" user:%s\n", *user)
	}
	connString := fmt.Sprintf("server=%s;database=%s;user id=%s;password=%s;port=%d;encrypt=disable", *server, *database2, *user, *password, *port)
	if *debug {
		fmt.Printf(" connString:%s\n", connString)
	}
	db, err := sql.Open("mssql", connString)
	if err != nil {
		log.Fatal("Open connection failed:", err.Error())
		return nil, err
	}
	err = db.Ping()
	if err != nil {
		fmt.Print("PING:%s", err)
		return nil, err
	}
	return db, nil
}

//tds_test.go中有windows登录代码

func TestSSPIAuth(t *testing.T) {
	if runtime.GOOS != "windows" {
		t.Skip("Only on windows")
	}
	checkConnStr(t)
	connStr := makeConnStr(t)
	params := connStr.Query()
	params.Set("Integrated Security", "sspi")
	connStr.RawQuery = params.Encode()

	db, err := sql.Open("mssql", connStr.String())
	if err != nil {
		t.Error("Open failed", err)
	}
	defer db.Close()

	row := db.QueryRow("select 1, 'abc'")

	var somenumber int64
	var somechars string
	err = row.Scan(&somenumber, &somechars)
	if err != nil {
		t.Error("scan failed", err)
	}
	if somenumber != int64(1) || somechars != "abc" {
		t.Errorf("Invalid values from query: want {%d,'%s'}, got {%d,'%s'}", int64(1), "abc", somenumber, somechars)
	}
}

func GetConnParams() (*msdsn.Config, error) {
	dsn := os.Getenv("SQLSERVER_DSN")
	const logFlags = 127
	if len(dsn) > 0 {
		params, err := msdsn.Parse(dsn)
		if err != nil {
			return nil, err
		}
		params.LogFlags = logFlags
		return &params, nil
	}
	if len(os.Getenv("HOST")) > 0 && len(os.Getenv("DATABASE")) > 0 {
		return &msdsn.Config{
			Host:     os.Getenv("HOST"),
			Instance: os.Getenv("INSTANCE"),
			Database: os.Getenv("DATABASE"),
			User:     os.Getenv("SQLUSER"),
			Password: os.Getenv("SQLPASSWORD"),
			LogFlags: logFlags,
		}, nil
	}
	// try loading connection string from file
	f, err := os.Open(".connstr")
	if err == nil {
		rdr := bufio.NewReader(f)
		dsn, err := rdr.ReadString('\n')
		if err != io.EOF && err != nil {
			return nil, err
		}
		params, err := msdsn.Parse(dsn)
		if err != nil {
			return nil, err
		}
		params.LogFlags = logFlags
		return &params, nil
	}

	return nil, nil
}

func checkConnStr(t testing.TB) {
	testConnParams(t)
}

// makeConnStr returns a URL struct so it may be modified by various
// tests before used as a DSN.
func makeConnStr(t testing.TB) *url.URL {
	return testConnParams(t).URL()
}

// returns parsed connection parameters derived from
// environment variables
func testConnParams(t testing.TB) msdsn.Config {
	params, err := GetConnParams()
	if err != nil {
		t.Fatal("unable to parse SQLSERVER_DSN or read .connstr", err)
	}
	if params == nil {
		t.Skip("no database connection string")
		return msdsn.Config{}
	}
	return *params
}
